﻿using BCCommon;
using BCCommon.NPinyin;
using BCData.TMS.MoveHouseConfig.MoveHouseConfig;
using BCData.TMS.MoveHouseConfig.MoveHouseServiceConfig;
using BCData.TMS.MoveHouseConfig.MoveHouseSpecificationConfig;
using BCData.TMS.MoveHouseConfig.MoveHouseSpecificationServiceConfig;
using BCDto.Sim.Admin.Admin;
using BCDto.TMS.MoveHouseConfig.MoveHouseSpecificationConfig;
using BCDto.TMS.MoveHouseConfig.MoveHouseSpecificationConfig.MoveHouseSpecificationConfigRequest;
using BCDto.TMS.MoveHouseConfig.MoveHouseSpecificationServiceConfig;
using BCEntity.Common.EntityNameConst;
using BCEntity.TMS.MoveHouseConfig.MoveHouseSpecificationConfig;
using BCEntity.TMS.MoveHouseConfig.MoveHouseSpecificationServiceConfig;
using BCService.Utils;
using System;
using System.Collections.Generic;
using System.Linq;

namespace BCService.TMS.MoveHouseConfig.MoveHouseSpecificationConfig
{
    public class MoveHouseSpecificationConfigService : IMoveHouseSpecificationConfigService
    {
        private readonly IMoveHouseSpecificationConfigData moveHouseSpecificationConfigData;
        private readonly IMoveHouseConfigData moveHouseConfigData;
        private readonly IDatabaseContext databaseContext;
        private readonly IMoveHouseSpecificationServiceConfigData moveHouseSpecificationServiceConfigData;
        private readonly IMoveHouseServiceConfigData moveHouseServiceConfigData;
        private readonly IRedisService redisService;
        private readonly string key = string.Format("{0}", EntityNameConst.MoveHouseSpecificationConfigEntity);
        private readonly string keyOverWrite = string.Format("{0}", EntityNameConst.MoveHouseSpecificationConfigOverWriteEntity);
        private readonly string keyView = string.Format("{0}", EntityNameConst.MoveHouseSpecificationConfigViewEntity);

        private readonly string keyService = string.Format("{0}", EntityNameConst.MoveHouseSpecificationServiceConfigEntity);
        private readonly string keyServiceOverWrite = string.Format("{0}", EntityNameConst.MoveHouseSpecificationServiceConfigOverWriteEntity);
        private readonly string keyServiceView = string.Format("{0}", EntityNameConst.MoveHouseSpecificationServiceConfigViewEntity);
        public MoveHouseSpecificationConfigService(IDatabaseContext databaseContext,
            IMoveHouseSpecificationConfigData moveHouseSpecificationConfigData,
            IMoveHouseConfigData moveHouseConfigData,
            IMoveHouseSpecificationServiceConfigData moveHouseSpecificationServiceConfigData,
            IRedisService redisService,
            IMoveHouseServiceConfigData moveHouseServiceConfigData)
        {
            this.databaseContext = databaseContext;
            this.moveHouseSpecificationConfigData = moveHouseSpecificationConfigData;
            this.moveHouseConfigData = moveHouseConfigData;

            this.moveHouseSpecificationServiceConfigData = moveHouseSpecificationServiceConfigData;
            this.redisService = redisService;
            this.moveHouseServiceConfigData = moveHouseServiceConfigData;
        }

        public MoveHouseSpecificationConfigDto Create(long moveHouseConfigId, MoveHouseSpecificationConfigRequestDto requestDto, AdminDto admin)
        {
            var moveHouseConfigEntity = moveHouseConfigData.GetSingle(moveHouseConfigId).Result;
            if (moveHouseConfigEntity == null)
            {
                throw new ArgumentException(" 获取搬家配置失败 ");
            }
            var parentMoveHouseConfigEntity = moveHouseConfigData.GetSingle(moveHouseConfigEntity.ParentId).Result;
            if (parentMoveHouseConfigEntity == null)
            {
                throw new ArgumentException(" 当前搬家分类选择不正确 ");
            }

            var isExist = this.moveHouseSpecificationConfigData.IsExist(requestDto.SpecificationName, moveHouseConfigId, null).GetAwaiter().GetResult();
            if (isExist)
            {
                throw new ArgumentException(" 当前搬家分类中存在此规格,不可重复添加 ");
            }
            var entity = new MoveHouseSpecificationConfigEntity
            {
                SpecificationName = requestDto.SpecificationName,
                SpecificationPinYin = Pinyin.GetCompactPinyin(requestDto.SpecificationName),
                MoveHouseConfigId = moveHouseConfigEntity.MoveHouseConfigId,
                MoveHouseConfigName = moveHouseConfigEntity.MoveHouseConfigName,
                ParentMoveHouseConfigId = parentMoveHouseConfigEntity.MoveHouseConfigId,
                ParentMoveHouseConfigName = parentMoveHouseConfigEntity.MoveHouseConfigName,
                Remark = requestDto.Remark,
                Enabled = requestDto.Enabled,
                CreateTime = DateTime.Now,
                CreateAdminId = admin.AdminId,
                CreateAdminName = admin.FullName,
                UpdateTime = DateTime.Now,
                EditAdminId = admin.AdminId,
                EditAdminName = admin.FullName,
            };
            var moveHouseSpecificationServiceConfigs = new List<MoveHouseSpecificationServiceConfigEntity>();
            foreach (var item in requestDto.SpecificationServiceRequests)
            {
                var moveHouseServiceConfigEntity = this.moveHouseServiceConfigData.GetSingle(item.SpecificationServiceConfigId).Result;
                if (moveHouseServiceConfigEntity == null)
                {
                    throw new ArgumentException(" 当前所选服务中存在数据错误 ");
                }
                var moveHouseSpecificationServiceConfig = new MoveHouseSpecificationServiceConfigEntity()
                {
                    MoveHouseConfigId = moveHouseConfigEntity.MoveHouseConfigId,
                    SpecificationName = entity.SpecificationName,
                    SpecificationServiceConfigId = moveHouseServiceConfigEntity.MoveHouseServiceConfigId,
                    SpecificationServiceName = moveHouseServiceConfigEntity.ServiceName,
                    Enabled = requestDto.Enabled,
                    Remark = item.Remark,
                    CreateTime = DateTime.Now,
                    CreateAdminId = admin.AdminId,
                    CreateAdminName = admin.FullName,
                    UpdateTime = DateTime.Now,
                    EditAdminId = admin.AdminId,
                    EditAdminName = admin.FullName,
                };
                moveHouseSpecificationServiceConfigs.Add(moveHouseSpecificationServiceConfig);
            }
            this.databaseContext.BeginTransaction();
            var moveHouseSpecificationConfigEntity = moveHouseSpecificationConfigData.InsertAsync(entity).GetAwaiter().GetResult();
            foreach (var item in moveHouseSpecificationServiceConfigs)
            {
                item.MoveHouseSpecificationConfigId = moveHouseSpecificationConfigEntity.MoveHouseSpecificationConfigId;
            }
            moveHouseSpecificationServiceConfigData.DeleteBySpecificationConfigId(moveHouseSpecificationConfigEntity.MoveHouseSpecificationConfigId).GetAwaiter().GetResult();
            var result = moveHouseSpecificationServiceConfigData.InsertAllAsync(moveHouseSpecificationServiceConfigs).GetAwaiter().GetResult();
            if (result != moveHouseSpecificationServiceConfigs.Count)
            {
                throw new ArgumentException(" 设置规格服务失败 ");
            }
            this.databaseContext.Commit();
            this.redisService.DeleteMultipleKey(keyService, false);
            this.redisService.DeleteMultipleKey(key, false);
            return moveHouseSpecificationConfigEntity.As<MoveHouseSpecificationConfigDto>();
        }

        public bool Update(long moveHouseSpecificationConfigId, MoveHouseSpecificationConfigRequestDto requestDto, AdminDto admin)
        {
            if (admin.CompanyId != 1)
            {
                throw new ArgumentException(" 用户认证失败,错误操作 ");
            }
            var entity = moveHouseSpecificationConfigData.GetSingle(moveHouseSpecificationConfigId).Result;
            if (entity == null)
            {
                throw new ArgumentException(" 获取搬家规格配置失败 ");
            }
            var isExist = this.moveHouseSpecificationConfigData.IsExist(requestDto.SpecificationName, entity.MoveHouseConfigId, moveHouseSpecificationConfigId).GetAwaiter().GetResult();
            if (isExist)
            {
                throw new ArgumentException(" 当前搬家分类中存在此规格,不可修改 ");
            }
            entity.SpecificationName = requestDto.SpecificationName;
            entity.Remark = requestDto.Remark;
            entity.Enabled = requestDto.Enabled;
            entity.UpdateTime = DateTime.Now;
            entity.EditAdminId = admin.AdminId;
            entity.EditAdminName = admin.FullName;
            var moveHouseSpecificationServiceConfigs = new List<MoveHouseSpecificationServiceConfigEntity>();
            foreach (var item in requestDto.SpecificationServiceRequests)
            {
                var moveHouseServiceConfigEntity = this.moveHouseServiceConfigData.GetSingle(item.SpecificationServiceConfigId).Result;
                if (moveHouseServiceConfigEntity == null)
                {
                    throw new ArgumentException(" 当前所选服务中存在数据错误 ");
                }
                var moveHouseSpecificationServiceConfig = new MoveHouseSpecificationServiceConfigEntity
                {
                    MoveHouseConfigId = entity.MoveHouseConfigId,
                    MoveHouseSpecificationConfigId = moveHouseSpecificationConfigId,
                    SpecificationName = entity.SpecificationName,
                    SpecificationServiceConfigId = moveHouseServiceConfigEntity.MoveHouseServiceConfigId,
                    SpecificationServiceName = moveHouseServiceConfigEntity.ServiceName,
                    Enabled = requestDto.Enabled,
                    Remark = item.Remark,
                    CreateTime = DateTime.Now,
                    CreateAdminId = admin.AdminId,
                    CreateAdminName = admin.FullName,
                    UpdateTime = DateTime.Now,
                    EditAdminId = admin.AdminId,
                    EditAdminName = admin.FullName,
                };
                moveHouseSpecificationServiceConfigs.Add(moveHouseSpecificationServiceConfig);
            }
            this.databaseContext.BeginTransaction();
            moveHouseSpecificationConfigData.UpdateAsync(entity).GetAwaiter().GetResult();
            moveHouseSpecificationServiceConfigData.DeleteBySpecificationConfigId(moveHouseSpecificationConfigId).GetAwaiter().GetResult();
            var result = moveHouseSpecificationServiceConfigData.InsertAllAsync(moveHouseSpecificationServiceConfigs).GetAwaiter().GetResult();
            if (result != moveHouseSpecificationServiceConfigs.Count)
            {
                throw new ArgumentException(" 设置规格服务失败 ");
            }
            this.databaseContext.Commit();
            this.redisService.DeleteMultipleKey(keyService, false);
            this.redisService.DeleteMultipleKey(key, false);
            return true;
        }

        public MoveHouseSpecificationConfigDto GetSingle(AdminDto admin, long moveHouseSpecificationConfigId)
        {
            string cacheKey = this.redisService.GetKey(key, moveHouseSpecificationConfigId);
            var resultRedis = this.redisService.TryGet(cacheKey, () =>
            {
                var entity = moveHouseSpecificationConfigData.GetSingle(moveHouseSpecificationConfigId).Result;
                var result = entity.As<MoveHouseSpecificationConfigDto>();
                if (result == null) return null;
                var entities = this.moveHouseSpecificationServiceConfigData.GetList(result.MoveHouseSpecificationConfigId,
                    null).Result.As<IEnumerable<MoveHouseSpecificationServiceConfigDto>>();
                result.MoveHouseSpecificationServiceConfigs = entities;
                return result;
            }, TimeSpan.FromMinutes(30));

            return resultRedis;
        }
        public IEnumerable<MoveHouseSpecificationConfigDto> GetList(AdminDto admin, long moveHouseConfigId, bool? isEnable)
        {
            string cacheKey = this.redisService.GetKey(key, moveHouseConfigId, isEnable);
            var result = this.redisService.TryGet(cacheKey, () =>
               {
                   var list = this.moveHouseSpecificationConfigData.GetList(moveHouseConfigId, isEnable).Result.As<IEnumerable<MoveHouseSpecificationConfigDto>>();
                   var moveHouseSpecificationConfigs = list.ToList();
                   foreach (var item in moveHouseSpecificationConfigs)
                   {
                       var entity = moveHouseSpecificationServiceConfigData.GetList(item.MoveHouseSpecificationConfigId,
                       isEnable).Result.As<IEnumerable<MoveHouseSpecificationServiceConfigDto>>();
                       item.MoveHouseSpecificationServiceConfigs = entity;
                   }
                   return moveHouseSpecificationConfigs;
               }, TimeSpan.FromMinutes(30));

            return result;
        }


        public IEnumerable<MoveHouseSpecificationConfigDto> GetAllList(AdminDto admin, long moveHouseConfigId, bool? isEnable)
        {

            long? resultMoveHouseConfigId = null;
            if (moveHouseConfigId > 0)
            {
                var moveHouseConfigEntity = this.moveHouseConfigData.GetSingle(moveHouseConfigId).Result;
                if (moveHouseConfigEntity == null)
                {
                    throw new ArgumentException(" 获取搬家设置信息失败 ");
                }
                resultMoveHouseConfigId = moveHouseConfigId;
            }
            string cacheKey = this.redisService.GetKey(key, resultMoveHouseConfigId, isEnable);
            var data = this.redisService.TryGet(cacheKey, () =>
            {
                var entities = this.moveHouseSpecificationConfigData.GetAllList(resultMoveHouseConfigId,
                    isEnable).Result.As<IEnumerable<MoveHouseSpecificationConfigDto>>().ToList();
                foreach (var item in entities)
                {
                    var entity = moveHouseSpecificationServiceConfigData.GetList(item.MoveHouseSpecificationConfigId,
                    isEnable).Result.As<IEnumerable<MoveHouseSpecificationServiceConfigDto>>();
                    item.MoveHouseSpecificationServiceConfigs = entity;
                }
                return entities;
            }, TimeSpan.FromMinutes(30));

            return data;
        }


        public bool Delete(long moveHouseSpecificationConfigId, AdminDto admin)
        {
            if (admin.CompanyId != 1)
            {
                throw new ArgumentException(" 用户认证失败,错误操作 ");
            }
            var moveHouseSpecificationConfigEntity = moveHouseSpecificationConfigData.GetSingle(moveHouseSpecificationConfigId).Result;
            if (moveHouseSpecificationConfigEntity == null)
            {
                throw new ArgumentException(" 获取当前搬家规格配置失败 ");
            }
            var specificationServices = moveHouseSpecificationServiceConfigData.GetList(moveHouseSpecificationConfigId, null).Result;
            if (specificationServices.Any())
            {
                throw new ArgumentException(" 当前搬家规格中存在服务,不可删除 ");
            }
            this.databaseContext.BeginTransaction();
            var moveHouseSpecificationServiceConfigResult = 0;
            var result = this.moveHouseSpecificationConfigData.DeleteAsync(moveHouseSpecificationConfigId).GetAwaiter().GetResult();
            if (result > 0)
            {
                moveHouseSpecificationServiceConfigResult = moveHouseSpecificationServiceConfigData.DeleteBySpecificationConfigId(moveHouseSpecificationConfigId).GetAwaiter().GetResult();
            }
            this.databaseContext.Commit();
            this.redisService.DeleteMultipleKey(key, false);
            if (moveHouseSpecificationServiceConfigResult > 0)
            {
                this.redisService.DeleteMultipleKey(keyService, false);
            }
            return true;
        }

        public bool Enabled(long moveHouseSpecificationConfigId, AdminDto admin)
        {
            if (admin.CompanyId != 1)
            {
                throw new ArgumentException(" 用户认证失败,错误操作 ");
            }
            var moveHouseSpecificationConfigEntity = moveHouseSpecificationConfigData.GetSingle(moveHouseSpecificationConfigId).Result;
            if (moveHouseSpecificationConfigEntity == null)
            {
                throw new ArgumentException(" 获取当前搬家规格配置失败 ");
            }
            var moveHouseConfigEntity = this.moveHouseConfigData.GetSingle(moveHouseSpecificationConfigEntity.MoveHouseConfigId).Result;
            if (moveHouseConfigEntity == null)
            {
                throw new ArgumentException(" 获取当前搬家配置失败,错误数据 ");
            }
            if (!moveHouseConfigEntity.Enabled)
            {
                throw new ArgumentException(" 当前规格所属的搬家分类配置被禁用,不可启用 ");
            }
            moveHouseSpecificationConfigEntity.Enabled = true;
            moveHouseSpecificationConfigEntity.UpdateTime = DateTime.Now;
            moveHouseSpecificationConfigEntity.EditAdminId = admin.AdminId;
            moveHouseSpecificationConfigEntity.EditAdminName = admin.FullName;
            this.moveHouseSpecificationConfigData.UpdateAsync(moveHouseSpecificationConfigEntity).GetAwaiter().GetResult();
            this.databaseContext.Commit();
            this.redisService.DeleteMultipleKey(key, false);
            return true;
        }

        public bool Disabled(long moveHouseSpecificationConfigId, AdminDto admin)
        {
            if (admin.CompanyId != 1)
            {
                throw new ArgumentException(" 用户认证失败,错误操作 ");
            }
            var moveHouseSpecificationConfigEntity = moveHouseSpecificationConfigData.GetSingle(moveHouseSpecificationConfigId).Result;
            if (moveHouseSpecificationConfigEntity == null)
            {
                throw new ArgumentException(" 获取当前搬家规格配置失败 ");
            }
            var specificationServices = moveHouseSpecificationServiceConfigData.GetList(moveHouseSpecificationConfigId, null).Result;
            if (specificationServices.Any())
            {
                throw new ArgumentException(" 当前搬家规格中存在服务,不可禁用 ");
            }
            moveHouseSpecificationConfigEntity.Enabled = false;
            moveHouseSpecificationConfigEntity.UpdateTime = DateTime.Now;
            moveHouseSpecificationConfigEntity.EditAdminId = admin.AdminId;
            moveHouseSpecificationConfigEntity.EditAdminName = admin.FullName;
            this.moveHouseSpecificationConfigData.UpdateAsync(moveHouseSpecificationConfigEntity).GetAwaiter().GetResult();
            this.databaseContext.Commit();
            this.redisService.DeleteMultipleKey(key, false);
            return true;
        }
    }
}
